package com.wxy;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;

import java.sql.*;
import java.util.Scanner;

public class Main {

    public static String DEFAULT_IP = "localhost";
    public static String DEFAULT_DB = "test";


    public static void main(String[] args) {
        // 程序终止时给出关闭提示
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown...")));
        // 主逻辑
        System.out.println("==================== Database Command Line Program ======================");
        System.out.println("Eg:                                                                      ");
        System.out.println("1.mysql -h[hostname] -P[port] -name[dbname] -u[username] -p[password]    ");
        System.out.println("2.oracle -h[hostname] -P[port] -sid[SID] -u[username] -p[password]       ");
        System.out.println("3.sqlserver -h[hostname] -P[port] -name[dbname] -u[username] -p[password]");
        System.out.println("4.pgsql -h[hostname] -P[port] -name[dbname] -u[username] -p[password]    ");
        System.out.println("5.db2 -h[hostname] -P[port] -name[dbname] -u[username] -p[password]      ");
        System.out.println("=========================================================================");
        Scanner scan = new Scanner(System.in);
        while (true) {
            try {
                System.out.println("Please enter the database connection command:");
                String nextLine = scan.nextLine().trim();
                if (nextLine.startsWith("exit")) {
                    System.out.println("The program is about to exit.");
                    break;
                }
                // 解析参数
                String host = ReUtil.getGroup1("-h\\[(.*?)\\]", nextLine);
                String port = ReUtil.getGroup1("-P\\[(.*?)\\]", nextLine);
                String dbname = ReUtil.getGroup1("-name\\[(.*?)\\]", nextLine);
                String username = ReUtil.getGroup1("-u\\[(.*?)\\]", nextLine);
                String password = ReUtil.getGroup1("-p\\[(.*?)\\]", nextLine);
                String sid = ReUtil.getGroup1("-sid\\[(.*?)\\]", nextLine);
                // 连接数据库
                System.out.println("Database connecting...");
                Connection conn;
                if (nextLine.startsWith("mysql")) {
                    Class.forName("com.mysql.cj.jdbc.Driver");
                    conn = DriverManager.getConnection("jdbc:mysql://" + (StrUtil.isNotBlank(host) ? host : DEFAULT_IP) + ":" + (StrUtil.isNotBlank(port) ? port : "3306") + "/" + (StrUtil.isNotBlank(dbname) ? dbname : DEFAULT_DB) + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai", username, password);
                } else if (nextLine.startsWith("oracle")) {
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                    conn = DriverManager.getConnection("jdbc:oracle:thin:@" + (StrUtil.isNotBlank(host) ? host : DEFAULT_IP) + ":" + (StrUtil.isNotBlank(port) ? port : "1521") + ":" + (StrUtil.isNotBlank(sid) ? sid : "ORCL"), username, password);
                } else if (nextLine.startsWith("sqlserver")) {
                    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                    conn = DriverManager.getConnection("jdbc:sqlserver://" + (StrUtil.isNotBlank(host) ? host : DEFAULT_IP) + ":" + (StrUtil.isNotBlank(port) ? port : "1433") + ";databasename=" + (StrUtil.isNotBlank(dbname) ? dbname : DEFAULT_DB), username, password);
                } else if (nextLine.startsWith("pgsql")) {
                    Class.forName("org.postgresql.Driver");
                    conn = DriverManager.getConnection("jdbc:postgresql://" + (StrUtil.isNotBlank(host) ? host : DEFAULT_IP) + ":" + (StrUtil.isNotBlank(port) ? port : "5432") + "/" + (StrUtil.isNotBlank(dbname) ? dbname : DEFAULT_DB), username, password);
                } else if (nextLine.startsWith("db2")) {
                    Class.forName("com.ibm.db2.jcc.DB2Driver");
                    conn = DriverManager.getConnection("jdbc:db2://" + (StrUtil.isNotBlank(host) ? host : DEFAULT_IP) + ":" + (StrUtil.isNotBlank(port) ? port : "50000") + "/" + (StrUtil.isNotBlank(dbname) ? dbname : DEFAULT_DB), username, password);
                } else {
                    System.out.println("Invalid command, please re-enter.");
                    continue;
                }
                System.out.println("Connection successful!!!");
                // 连接成功，执行sql语句
                Statement st = conn.createStatement();
                while (true) {
                    try {
                        System.out.println("Please enter the sql statement: [Enter 'exit' to exit]");
                        String sql = scan.nextLine().trim();
                        String validSql = sql.toLowerCase();
                        if (validSql.startsWith("exit")) {// 退出
                            System.out.println("The program is about to exit.");
                            break;
                        } else {
                            System.out.println("----");
                            if (validSql.startsWith("select") || validSql.startsWith("show tables") || validSql.startsWith("desc")) {
                                ResultSet rs = st.executeQuery(sql);
                                ResultSetPrinter.printResultSet(rs);
                                rs.close();
                            } else if (validSql.startsWith("insert") || validSql.startsWith("update")
                                    || validSql.startsWith("delete")) {
                                int count = st.executeUpdate(sql);
                                System.out.println("Query ok, " + count + " rows affected!");
                            } else if (validSql.startsWith("create") || validSql.startsWith("alter") || validSql.startsWith("drop")) {
                                boolean bool = st.execute(sql);
                                System.out.println(bool ? "Query ok!" : "Query failed!");
                            } else {
                                System.out.println("Invalid sql statement!");
                            }
                            System.out.println("----");
                        }
                    } catch (SQLException e) {
                        e.printStackTrace();
                        System.out.println("Sql statement execution failed!");
                    }
                }
                st.close();
                conn.close();
                break;
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
                System.out.println("Unable to connect to the database, please try again!");
            }
        }
        scan.close();
        System.out.println("Shutdown...");
    }
}
